if (!window.DOMDelegate) window.DOMDelegate = {};

DOMDelegate.__MS_DOC_Names__ = [
    "MSXML2.DOMDocument.5.0", "MSXML2.DOMDocument.4.0", "MSXML2.DOMDocument.3.0",
    "MSXML2.DOMDocument", "Microsoft.XmlDom"
];

DOMDelegate.createDocument = function ()
{
    if (window.navigator.userAgent.indexOf ("MSIE") >= 0) return __GetMSDoc__ ();
    else if (document.implementation && document.implementation.createDocument)
        return __GetGeckoDoc__ ();
    else
        throw "Your browser doesn't support an XML DOM object.";
}

DOMDelegate.getNodeValue = function (node)
{
    if (node.firstChild) return node.firstChild.nodeValue;
    return node.nodeValue;
}

function __GetMSDoc__ ()
{
    for (var i = 0; i < DOMDelegate.__MS_DOC_Names__.length; i ++) {
        try {
            return new ActiveXObject (DOMDelegate.__MS_DOC_Names__ [i]);
        } catch (ex) {
        }
    }
    throw "MSXML is not installed on your system.";
}

function __GetGeckoDoc__ ()
{
    __Fix_Gecko_DOM ();
    var doc = document.implementation.createDocument ("", "", null);
    
    doc.parseError = {
        valueOf: function () {
            return this.errorCode;
        },
        toString: function () {
            return this.errorCode.toString ();
        }
    };
    doc.__initError__ ();
    doc.addEventListener ("load", function () {
        this.__initError__ ();
        this.__changeReadyState__ (4);
    }, false);
    return doc;
}

function __Fix_Gecko_DOM ()
{   
    Document.prototype.readyState = 0;
    Document.prototype.onreadystatechange = null;
    Document.prototype.__load__ = Document.prototype.load;

    Document.prototype.__changeReadyState__ = __Gecko_changeReadyState__;
    Document.prototype.__initError__ = __InitError__;
    Document.prototype.__checkError__ = __CheckForError__;
    Document.prototype.__defineGetter__ ("xml", __Gecko_GetXML);

    Document.prototype.load = __Gecko_Load__;
    Document.prototype.loadXML = __Gecko_LoadXML__;
    Document.prototype.selectSingleNode = __Gecko_SelectSingleNode__;
    Document.prototype.selectNodes = __Gecko_SelectNodes__;
    Document.prototype.transformNode = __Gecko_transformNode__;
    Element.prototype.selectSingleNode = __Gecko_SelectSingleNode__;
    Element.prototype.selectNodes = __Gecko_SelectNodes__;
    Element.prototype.transformNode = __Gecko_transformNode__;
}

function __Gecko_LoadXML__ (content)
{
    this.__initError__ ();
    this.__changeReadyState__ (1);
    var parser = new DOMParser ();
    var doc = parser.parseFromString (content, "text/xml");
    while (this.firstChild) this.removeChild (this.firstChild);
    for (var i = 0; i < doc.childNodes.length; i ++) {
        var node = this.importNode (doc.childNodes[i], true);
        this.appendChild (node);
    }
    this.__checkError__ ();
    this.__changeReadyState__ (4);
}

function __Gecko_GetXML ()
{
    return new XMLSerializer ().serializeToString (this, "text/xml");
}

function __Gecko_changeReadyState__ (state)
{
    var ff36 = window.navigator.userAgent.indexOf("Firefox/3.6") >= 0
    if (!ff36)
        this.readyState = state;
    if (typeof this.onreadystatechange == "function")
        this.onreadystatechange ();
}

function __Gecko_Load__ (url)
{
    this.__CheckForError__ ();
    this.__changeReadyState__ (1);
    this.__load__ (url);
}

function __InitError__ ()
{
    this.parseError.errorCode = 0;
    this.parseError.filepos = -1;
    this.parseError.line = -1;
    this.parseError.linepos = -1;
    this.parseError.reason = null;
    this.parseError.srcText = null;
    this.parseError.url = null;
}

function __CheckForError__ ()
{
    if (this.documentElement.tagName == "parsererror")
    {
        var reError = />([\s\S]*?)Location: ([\s\S]*?])Row: ([\d]*?), Column: ([\d]*?)<sourcetext>([\s\S]*?)(?:\-*\^)/;
        var content = this.xml;
        var found = reError.test (content);
        if (!found)
        {
            reError = />XML解析错误：([\s\S]*?)位置：([\s\S]*?)行：([\d]*?)，列：([\d]*?)<sourcetext>([\s\S]*?)(?:\-*\^)/;
            found = reError.test (content);
        }

        var reason = "Unknown Error";
        var url = "Unknown resource";
        var line = -1;
        var col = -1;
        var srcText = null;
        if (found)
        {
            
            reError.test (this.xml);
            reason = RegExp.$1;
            url = RegExp.$2;
            line = RegExp.$3;
            col = RegExp.$4;
            srcText = RegExp.$5;
        }

        this.parseError.errorCode = -99999;
        this.parseError.reason = reason.trim ();
        this.parseError.url = url.trim ();
        this.parseError.line = parseInt (line, 10);
        this.parseError.linepos = parseInt (col, 10);
        this.parseError.srcText = srcText.trim ();
    }
}

function __Gecko_SelectSingleNode__ (xpath)
{
    var evaluator = new XPathEvaluator ();
    var result = evaluator.evaluate (xpath, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
    if (result != null)
        return result.singleNodeValue;
    return null;
}

function __Gecko_SelectNodes__ (xpath)
{
    var evaluator = new XPathEvaluator ();
    var result = evaluator.evaluate (xpath, this, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
    if (result != null)
    {
        var nodeList = new Array ();
        var e = result.iterateNext ();
        while (e)
        {
            nodeList.push (e);
            e = result.iterateNext ();
        }
        return nodeList;
    }
    return null;
}

function __Gecko_transformNode__ (xsl)
{
    var processor = new XSLTProcessor ();
    processor.importStylesheet (xsl);
    var obj = processor.transformToDocument (this);
/*
    var result = obj.xml;

    if (result.indexOf ("<transformiix:result") > -1)
        result = result.substring (result.indexOf (">") + 1, result.lastIndexOf("<"));
*/
//    return result;
    return obj;
}
